#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define NUM_THREADS     4

/* Begin My Snippet */
#include <semaphore.h>
sem_t mutex_alice;
sem_t mutex_john;
sem_t mutex_mary;
sem_t mutex_tom;

void mic_init ()
{
   if ( sem_init ( &mutex_alice, 0, 1) == -1 )
   {
      printf ( "alice semaphore init" );
   }
   if ( sem_init ( &mutex_john, 0, 0) == -1 )
   {
      printf ( "john semaphore init" );
   }
   if ( sem_init ( &mutex_mary, 0, 0) == -1 )
   {
      printf ( "mary semaphore init" );
   }
   if ( sem_init ( &mutex_tom, 0, 0) == -1 )
   {
      printf ( "tom semaphore init" );
   }
}

void mic_request (void *ptr)
{
   char *filename = (char *) ptr;
   if ( !strcmp ( filename, "Alice" ))
   {
      sem_wait ( &mutex_alice );
   }
   else if ( !strcmp ( filename, "John" ))
   {
      sem_wait ( &mutex_john );
   }
   else if ( !strcmp ( filename, "Mary" ))
   {
      sem_wait ( &mutex_mary );
   }
   else /* Assume Tom */
   {
      sem_wait ( &mutex_tom );
   }
}

void mic_relinquish (void *ptr)
{
   char *filename = (char *) ptr;
   if ( !strcmp ( filename, "Alice" ))
   {
      sem_post ( &mutex_john );
   }
   else if ( !strcmp ( filename, "John" ))
   {
      sem_post ( &mutex_mary );
   }
   else if ( !strcmp ( filename, "Mary" ))
   {
      sem_post ( &mutex_tom );
   }
   else /* Assume Tom*/
   {
      sem_post ( &mutex_alice );
   }
}

/* End My Snippet */

void *participant(void *ptr)
{
   FILE *file;
   char *filename, chatline[100];
   long int i;

   filename = (char *) ptr;
   file = fopen(filename, "r");
   if (file != NULL)
   {
     while(fscanf(file, "%s\n", chatline) != EOF)
     {
       if (!strcmp (chatline, "MicRequest"))
       {
				 mic_request(ptr);
       }
       printf ("%s:%s\n",filename, chatline); 
       if (!strcmp (chatline, "MicRelinquish")) 
       {
				 mic_relinquish(ptr);
       }
			 //usleep(100000);   /* User "Thinking" Delay */
     }
          /*C9zv2fr3*/
   }
   fclose(file);
}

int main (int argc, char *argv[])
{
   pthread_t thread[NUM_THREADS];

   mic_init();
   pthread_create(&thread[0], NULL, participant, (void *)"Alice");
   pthread_create(&thread[1], NULL, participant, (void *)"John");
   pthread_create(&thread[2], NULL, participant, (void *)"Mary");
   pthread_create(&thread[3], NULL, participant, (void *)"Tom");
   getchar();
}
